﻿#region Using directives
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Net;
using System.Web.Script.Services;
using System.Web.Services;
using System.Xml;
using System.Xml.Linq;

#endregion

namespace ProcolServices {
    /// <summary>
    /// Summary description for GeolocationService
    /// </summary>
    [WebService(Namespace = "http://tempuri.org/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    [ToolboxItem(false)]
    [ScriptService]
    public class GeolocationService : WebService {
        private static readonly Dictionary<String, XDocument> cacheDb = new Dictionary<string, XDocument>();

        [WebMethod]
        public string[] GetGeoInfo(String ipAddr) {
            var geoInfo =
                    (from c in
                         GetXmlOrCache(String.Format("http://iploc.mwudka.com/iploc/{0}/xml", ipAddr)).Elements(
                         "location")
                     // ReSharper disable PossibleNullReferenceException
                     select new { Latitude = c.Element("latitude"), Longitude = c.Element("longitude") }).SingleOrDefault();
            // ReSharper restore PossibleNullReferenceException

            return new[] { geoInfo.Latitude.Value, geoInfo.Longitude.Value };
        }

        private static XDocument GetXmlOrCache(String cacheLocation) {
            if (cacheDb.ContainsKey(cacheLocation))
                return cacheDb[cacheLocation];

            try {
                if (InTec()) {
                    // Proxy del tec
                    var wp = new WebProxy("proxy.ccm.itesm.mx", 8080) { Credentials = new NetworkCredential("", "") };
                    var wc = new WebClient { Proxy = wp };

                    var ms = new MemoryStream(wc.DownloadData(cacheLocation));
                    var rdr = new XmlTextReader(ms);

                    cacheDb[cacheLocation] = XDocument.Load(rdr);
                } else
                    cacheDb[cacheLocation] = XDocument.Load(cacheLocation);
            } catch (WebException) {
                cacheDb[cacheLocation] = XDocument.Parse(@"<location ip=""189.216.76.66"">
<country_code>MX</country_code>
<country_code3>MEX</country_code3>
<country_name>Mexico</country_name>
<region>09</region>
<city>Mexico</city>
<postal_code/>
<latitude>19.4342</latitude>
<longitude>-99.1386</longitude>
<area_code/>
<dma_code/>
</location>");
            }

            return cacheDb[cacheLocation];
        }

        private static bool InTec() {
            String localName = Dns.GetHostName();
            IPAddress[] localIPs = Dns.GetHostAddresses(localName);

            foreach (var ip in localIPs) {
                if (ip.ToString().StartsWith("10.48."))
                    return true;
            }

            return false;
        }
    }
}